package com.zxl.placeholderParse;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


//import org.apache.commons.lang3.StringUtils;

//import com.hnair.middlegroup.app.cache.CacheKey;
//import com.hnair.middlegroup.app.domain.param.root.CommonDTO;
//import com.hnair.middlegroup.app.i18n.LanguageCodeUtil;
//import com.hnair.middlegroup.app.service.I18nService;
//import com.hnair.middlegroup.app.service.common.cache.CacheKit;

public class I18nKit {
    
//    private I18nService i18nService;
    
    /**
     * 获取国际化信息
     * @param keyCode   对应数据库的keyCode
     * @param cacheKey  对应的缓存key
     * @param dto       请求参数
     * @return
     */
//    public String getValue(String keyCode, CacheKey cacheKey, CommonDTO dto){
//        if (StringUtils.isBlank(keyCode)) {
//            return null;
//        }
//        String langCode = LanguageCodeUtil.getLangCode(dto.getSlang());
//        String key = cacheKey.appendParamKey(langCode);
//        Map<String, String> map = CacheKit.get(key);
//        if (map == null || map.isEmpty()) {
//            map = i18nService.getValues(key.split("_")[2], langCode);
//            if (map != null && !map.isEmpty()) {
//                if (cacheKey.getSecond() > 0) {
//                    CacheKit.set(key, map, cacheKey.getSecond());
//                }else {
//                    CacheKit.set(key, map);
//                }
//            }
//        }
//        return map == null ? null : map.get(keyCode);
//    }
    
    /**
     * 获取国际化信息
     * 如在数据库中存入以下国际化语句可使用本方法：
     *      这是一{?}测试{?}
     *      传入params为["条"，"语句"]
     *   调用该方法将返回 ： 这是一条测试语句
     *   注意：params的值顺序和占位符顺序一致
     * @param keyCode   对应数据库的keyCode
     * @param cacheKey  对应的缓存key
     * @param dto       请求参数
     * @param params    用以填充占位符的参数，占位符为{?} 
     * @return
     */
//    public String getValue(String keyCode, CacheKey cacheKey, CommonDTO dto, String... params){
//        return replaceParam(getValue(keyCode, cacheKey, dto),params);
//    }
    
    /**
     * 获取国际化信息
     * 如在数据库中存入以下国际化语句可使用本方法：
     *      他的名字是{name}，今年{age}岁
     *      传入paramMap中的key和占位符中的字符串匹配
     *   调用该方法将返回 ：他的名字是王老五，今年36岁
     * @param keyCode   对应数据库的keyCode
     * @param cacheKey  对应的缓存key
     * @param dto       请求参数
     * @param paramMap  用以填充占位符的参数 
     * @return
     */
//    public String getValue(String keyCode, CacheKey cacheKey, CommonDTO dto, Map<String, String> paramMap){
//        return replaceParam(getValue(keyCode, cacheKey, dto),paramMap);
//    }
	
    /**
     * 获取国际化信息
     * 如在数据库中存入以下国际化语句可使用本方法：
     *      他的名字是{name}，今年{age}岁
     *      传入paramObj为一个I18nBean对象，该对象存在name和age参数，并且都提供了get方法
     *   调用该方法将返回 ： 他的名字是王老五，今年36岁
     *   注意：参数名称需符合英文java命名规范
     * @param keyCode   对应数据库的keyCode
     * @param cacheKey  对应的缓存key
     * @param dto       请求参数
     * @param paramObj    用以填充占位符的对象 
     * @return
     */
//    public String getValue(String keyCode, CacheKey cacheKey, CommonDTO dto, I18nBean paramObj){
//        return replaceParam(getValue(keyCode, cacheKey, dto),paramObj);
//    }
    
	 /**
     * 纯?的占位符替换
     * 如现有以下需要需要处理的字符串：
     *      他的名字是{name}，今年{age}岁
     *      传入params为一个数组对象，该对象长度不低于占位符数量，存放顺序和占位符顺序要一致，否则可能不是想要的结果
     * 执行成功后返回 ： 	他的名字是张三，今年36岁
     * @param str       待处理的字符串
     * @param params  用以填充占位符的列表
     * @return
     */
    public static String replaceParam(String str, String... params){
        if (str == null || params == null || params.length == 0) {
            return str;
        }
        Pattern pattern = Pattern.compile("\\{\\?\\}", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        int i = 0;
        while (matcher.find()) {
            if (i < params.length) {
                matcher.appendReplacement(sb, params[i++]);
            }
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
    
    /**
     * 带名称的占位符替换
     * 如现有以下需要需要处理的字符串：
     *      他的名字是{name}，今年{age}岁
     *      传入paramMap为一个Map对象，该对象长度不低于占位符数量，key name存放张三，key age存放36
     * 执行成功后返回 ： 	他的名字是张三，今年36岁
     * @param str       待处理的字符串
     * @param paramMap  用以填充占位符的列表
     * @return
     */
    public static String replaceParam(String str, Map<String, String> paramMap){
        if (str == null || paramMap == null || paramMap.isEmpty()) {
            return str;
        }
        Pattern pattern = Pattern.compile("\\{([\\w$]+)\\}", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String value = paramMap.get(matcher.group(1));
            if (value != null) {
                matcher.appendReplacement(sb, value);
            }
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
    
    /**
     * 带索引的占位符替换
     * 如现有以下需要需要处理的字符串：
     *      他的名字是{0}，今年{1}岁
     *      传入params为一个List对象，该对象长度不低于占位符数量，索引0存放张三，索引1存放36
     * 执行成功后返回 ： 他的名字是张三，今年36岁
     * @param str       待处理的字符串
     * @param params  用以填充占位符的列表
     * @return
     */
    public static String replaceParam(String str, List<String> params){
    	if (str == null || params == null || params.isEmpty()) {
    		return str;
    	}
    	Pattern pattern = Pattern.compile("\\{(\\d+)\\}", Pattern.CASE_INSENSITIVE);
    	Matcher matcher = pattern.matcher(str);
    	StringBuffer sb = new StringBuffer();
    	while (matcher.find()) {
    		String value = params.get(Integer.parseInt(matcher.group(1)));
    		if (value != null) {
    			matcher.appendReplacement(sb, value);
    		}
    	}
    	matcher.appendTail(sb);
    	return sb.toString();
    }
    
    /**
     * 带名称的占位符替换
     * 如现有以下需要需要处理的字符串：
     *      他的名字是{name}，今年{age}岁
     *      传入paramObj为一个I18nBean对象，该对象存在name和age参数，并且都提供了get方法
     * 执行成功后返回 ： 他的名字是张三，今年36岁
     *   注意：参数名称需符合英文java命名规范
     * @param str       待处理的字符串
     * @param paramObj  用以填充占位符的对象 
     * @return
     */
    public static String replaceParam(String str, Serializable paramObj){
        if (str == null || paramObj == null ) {
            return str;
        }
        Pattern pattern = Pattern.compile("\\{([a-zA-Z_$]+[a-zA-Z_$\\d]*)\\}", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        Class<? extends Object> cls = paramObj.getClass();
        String group = "";
        char oldChar = 'a';
        Method method = null;
        Object value = null;
        try {
            while (matcher.find()) {
                group = matcher.group(1);
                oldChar = group.charAt(0);
                method = cls.getMethod("get" + group.replace(oldChar, Character.toUpperCase(oldChar)));
                value = method.invoke(paramObj);
                if (value != null) {
                    matcher.appendReplacement(sb, value.toString());
                }
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
}
